<link rel="import" href="../../html/polymer.html">

<link rel="import" href="../../html/assert.html">
<link rel="import" href="chrome://resources/polymer/v1_0/paper-styles/color.html">
<link rel="import" href="../hidden_style_css.html">
<link rel="import" href="../shared_style_css.html">
<link rel="import" href="../shared_vars_css.html">
<link rel="import" href="cr_input_style_css.html">

<dom-module id="cr-input">
  <template>
    <style include="cr-hidden-style cr-input-style cr-shared-style">
      /*
        A 'suffix' element will be outside the underlined space, while a
        'inline-prefix' and 'inline-suffix' elements will be inside the
        underlined space by default.

        Regarding cr-input's width:
        When there's no element in the 'inline-prefix', 'inline-suffix' or
        'suffix' slot, setting the width of cr-input as follows will work as
        expected:

          cr-input {
            width: 200px;
          }

        However, when there's an element in the 'suffix', 'inline-suffix' and/or
        'inline-prefix' slot, setting the 'width' will dictate the total width
        of the input field *plus* the 'inline-prefix', 'inline-suffix' and
        'suffix' elements. To set the width of the input field +
        'inline-prefix' + 'inline-suffix' when a 'suffix' is present,
        use --cr-input-width.

          cr-input {
            --cr-input-width: 200px;
          }
      */

      /* Disabled status should not impact suffix slot. */
      :host([disabled]) :-webkit-any(#label, #error, #input-container) {
        opacity: var(--cr-disabled-opacity);
        pointer-events: none;
      }

      /* Margin between <input> and <cr-button> in the 'suffix' slot */
      :host ::slotted(cr-button[slot=suffix]) {
        margin-inline-start: var(--cr-button-edge-spacing) !important;
      }

      :host([invalid]) #label {
        color: var(--cr-input-error-color);
      }

      #input {
        border-bottom: var(--cr-input-border-bottom, none);
        letter-spacing: var(--cr-input-letter-spacing);
      }

      #input::placeholder {
        color: var(--cr-input-placeholder-color, var(--cr-secondary-text-color));
        letter-spacing: var(--cr-input-placeholder-letter-spacing);
      }

      :host([invalid]) #input {
        caret-color: var(--cr-input-error-color);
      }

      :host([readonly]) #input {
        opacity: var(--cr-input-readonly-opacity, 0.6);
      }

      :host([invalid]) #underline {
        border-color: var(--cr-input-error-color);
      }

      /* Error styling below. */
      #error {
        /* Defaults to "display: block" and "visibility:hidden" to allocate
           space for error message, such that the page does not shift when
           error appears. For cr-inputs that can't be invalid, but are in a
           form with cr-inputs that can be invalid, this space is also desired
           in order to have consistent spacing.

           If spacing is not needed, apply "--cr-input-error-display: none".

           When grouping cr-inputs horizontally, it might be helpful to set
           --cr-input-error-white-space to "nowrap" and set a fixed width for
           each cr-input so that a long error label does not shift the inputs
           forward. */
        color: var(--cr-input-error-color);
        display: var(--cr-input-error-display, block);
        font-size: var(--cr-form-field-label-font-size);
        height: var(--cr-form-field-label-height);
        line-height: var(--cr-form-field-label-line-height);
        margin: 8px 0;
        visibility: hidden;
        white-space: var(--cr-input-error-white-space);
      }

      :host([invalid]) #error {
        visibility: visible;
      }

      #row-container,
      #inner-input-container {
        align-items: center;
        display: flex;
        /* This will spread the input field and the suffix apart only if the
           host element width is intentionally set to something large. */
        justify-content: space-between;
        position: relative;
      }

      #input[type='search']::-webkit-search-cancel-button {
        display: none;
      }

      :host-context([dir=rtl]) #input[type=url] {
        text-align: right;  /* csschecker-disable-line left-right */
      }

      #input[type=url] {
        direction: ltr;
      }
    </style>
    <div id="label" class="cr-form-field-label" hidden="[[!label]]"
        aria-hidden="true">
      [[label]]
    </div>
    <div id="row-container" part="row-container">
      <div id="input-container">
        <div id="inner-input-container">
          <slot name="inline-prefix"></slot>
          <!-- Only attributes that are named inconsistently between html and js
              need to use attr$="", such as |tabindex| vs .tabIndex and
              |readonly| vs .readOnly. -->
          <input id="input" disabled="[[disabled]]" autofocus="[[autofocus]]"
              value="{{value::input}}" tabindex$="[[tabindex]]" type="[[type]]"
              readonly$="[[readonly]]" maxlength$="[[maxlength]]"
              pattern$="[[pattern]]" required="[[required]]"
              minlength$="[[minlength]]" inputmode$="[[inputmode]]"
              aria-description$="[[ariaDescription]]"
              aria-label$="[[getAriaLabel_(ariaLabel, label, placeholder)]]"
              aria-invalid$="[[getAriaInvalid_(invalid)]]"
              max="[[max]]" min="[[min]]" on-focus="onInputFocus_"
              on-blur="onInputBlur_" on-change="onInputChange_"
              on-keydown="onInputKeydown_" part="input"
              autocomplete="off">
          <slot name="inline-suffix"></slot>
        </div>
        <div id="underline"></div>
      </div>
      <slot name="suffix"></slot>
    </div>
    <div id="error" aria-live="assertive">[[displayErrorMessage_]]</div>
  </template>
  <script src="cr_input.js"></script>
</dom-module>
